package com.example.demo.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Slf4j
@Component
public class MyLogAspect {
//    @Pointcut("execution(public * com.example..*.*(..))")
//    public void p() {
//    }

//    @Before("p()")
//    public void test(JoinPoint pjp) throws Throwable {
//        Object[] args = pjp.getArgs();
//        Signature signature = pjp.getSignature();
//        log.info("before:execute {}#{}, args = {}", signature.getDeclaringType(), signature.getName(), args);
//    }

    @Order
    @Pointcut("@annotation(com.example.demo.aop.MyLog)")
    public void p() {
    }

    @Around("p()")
    public Object test(ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        Signature signature = pjp.getSignature();

        long begin = System.currentTimeMillis();
        Object proceed = pjp.proceed();
        long end = System.currentTimeMillis();

        log.info("before:execute {}#{}, args = {}, cost = {}",
                signature.getDeclaringType(), signature.getName(), args, end - begin);
        return proceed;
    }
    // jdk proxy+invocationhandler => 性能略弱一点 | 被代理对象必须实现接口
    // cglib 动态操作字节码 => 性能强、无需接口 |
}
